package com.caiheng.api.service.examine.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.caiheng.api.util.OrderUtil;
import com.vdurmont.emoji.EmojiParser;
import com.caiheng.api.dao.examine.*;
import com.caiheng.api.entity.estate.Estate;
import com.caiheng.api.entity.estate.Property;
import com.caiheng.api.entity.examine.*;
import com.caiheng.api.entity.sys.SysUser;
import com.caiheng.api.entity.wxuser.User;
import com.caiheng.api.exception.TransactionalException;
import com.caiheng.api.service.base.impl.BaseServiceImpl;
import com.caiheng.api.service.estate.EstateService;
import com.caiheng.api.service.estate.PropertyService;
import com.caiheng.api.service.examine.ExamineApproveRegRecordService;
import com.caiheng.api.service.platfom.WxTemplateService;
import com.caiheng.api.service.wxuser.UserService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 审批申请记录Service业务层处理
 *
 * @author ruoyi
 * @date 2022-11-23
 */
@Service
public class ExamineApproveRegRecordServiceImpl extends BaseServiceImpl<ExamineApproveRegRecordMapper, ExamineApproveRegRecord> implements ExamineApproveRegRecordService {

    @Resource
    private ExamineApproveRegRecordMapper approveRegRecordMapper;
    @Resource
    private ExamineApproveRegAdminRecordMapper approveRegAdminRecordMapper;
    @Resource
    private ExamineApproveRegInfoMapper approveRegInfoMapper;
    @Resource
    private ExamineApproveRegImgMapper approveRegImgMapper;
    @Resource
    private ExamineApproveTemplateUserMapper approveTemplateUserMapper;
    @Resource
    private ExamineApproveMapper approveMapper;
    @Resource
    private UserService userService;
    @Resource
    private PropertyService propertyService;
    @Resource
    private EstateService estateService;
    @Resource
    private WxTemplateService wxTemplateService;

    @Value("${web.imgPrefix}")
    private String imgPrefix;

    @Override
    public ExamineApproveRegRecord getDetail(int userId, int recordId) {
        ExamineApproveRegRecord regRecord = approveRegRecordMapper.selectById(recordId);
        if(regRecord != null){

            QueryWrapper<ExamineApproveRegInfo> qwInfo = new QueryWrapper<>();
            qwInfo.eq("approve_record_id",recordId);
            qwInfo.orderByAsc("id");
            List<ExamineApproveRegInfo> infos = approveRegInfoMapper.selectList(qwInfo);
            regRecord.setRegInfos(infos);


            QueryWrapper<ExamineApproveRegImg> qwImg = new QueryWrapper<>();
            qwImg.eq("approve_record_id",recordId);
            List<ExamineApproveRegImg> imgs = approveRegImgMapper.selectList(qwImg);
            if(CollUtil.isNotEmpty(imgs)){
                for (ExamineApproveRegImg regImg : imgs){
                    regImg.setImgUrl(imgPrefix + regImg.getImgUrl());
                }
            }
            regRecord.setRegImgs(imgs);

            regRecord.setIsCanCheck(0);



            QueryWrapper<ExamineApproveRegAdminRecord> qwLastAdminRecord = new QueryWrapper<>();
            qwLastAdminRecord.eq("approve_record_id",recordId);
            qwLastAdminRecord.eq("state",0);
            qwLastAdminRecord.orderByDesc("id");
            qwLastAdminRecord.last("limit 1");
            ExamineApproveRegAdminRecord lastRegAdminRecord = approveRegAdminRecordMapper.selectOne(qwLastAdminRecord);
            if(lastRegAdminRecord != null){
                ExamineApproveTemplateUser templateUser = approveTemplateUserMapper.selectById(lastRegAdminRecord.getTemplateUserId());
                if(templateUser!=null){
                    lastRegAdminRecord.setUserName(templateUser.getUserName());
                }
                if(lastRegAdminRecord.getUserId()!= null && lastRegAdminRecord.getUserId().intValue() == userId){
                    regRecord.setIsCanCheck(1);
                }
            }
            regRecord.setLastRegAdminRecord(lastRegAdminRecord);

            ExamineApprove approve = approveMapper.selectById(regRecord.getApproveId());

            QueryWrapper<ExamineApproveTemplateUser> qwUser = new QueryWrapper<>();
            qwUser.eq("template_id", approve.getTemplateId());
//            qwUser.eq("is_end", 0);
            qwUser.eq("is_copy", 0);
            qwUser.orderByAsc("duty_index");
            List<ExamineApproveTemplateUser> templateUsers = approveTemplateUserMapper.selectList(qwUser);
            if(CollUtil.isNotEmpty(templateUsers)){
                for (ExamineApproveTemplateUser templateUser : templateUsers){
                    User user = userService.findById(templateUser.getUserId());
                    if(user != null){
                        if(StrUtil.isNotEmpty(user.getNickName())){
                            templateUser.setNickName(EmojiParser.parseToUnicode(user.getNickName()));
                        }
                        if(StrUtil.isNotEmpty(user.getFaceUrl())){
                            templateUser.setFaceUrl(user.getFaceUrl());
                            if(user.getFaceUrl().indexOf("https") < 0){
                                templateUser.setFaceUrl(imgPrefix + user.getFaceUrl());
                            }
                        }
                    }

                    QueryWrapper<ExamineApproveRegAdminRecord> qwAdminRecord = new QueryWrapper<>();
                    qwAdminRecord.eq("approve_record_id", recordId);
                    qwAdminRecord.eq("template_user_id",templateUser.getId());
                    qwAdminRecord.eq("user_id", templateUser.getUserId());
                    qwAdminRecord.last("limit 1");
                    ExamineApproveRegAdminRecord adminRecord = approveRegAdminRecordMapper.selectOne(qwAdminRecord);
                    if(adminRecord != null){
                        templateUser.setAdminRecord(adminRecord);
                    }else{
                        adminRecord = new ExamineApproveRegAdminRecord();
                        adminRecord.setState(0);
                        templateUser.setAdminRecord(adminRecord);
                    }
                }
            }
            regRecord.setTemplateUsers(templateUsers);


            QueryWrapper<ExamineApproveTemplateUser> qwUserCopy = new QueryWrapper<>();
            qwUserCopy.eq("template_id",approve.getTemplateId());
//            qwUserCopy.eq("is_end", 1);
            qwUserCopy.eq("is_copy", 1);
            List<ExamineApproveTemplateUser> copyTemplateUsers= approveTemplateUserMapper.selectList(qwUserCopy);
            if(CollUtil.isNotEmpty(copyTemplateUsers)){
                for (ExamineApproveTemplateUser templateUser : copyTemplateUsers) {
                    User user = userService.findById(templateUser.getUserId());
                    if (user != null) {
                        if (StrUtil.isNotEmpty(user.getNickName())) {
                            templateUser.setNickName(EmojiParser.parseToUnicode(user.getNickName()));
                        }
                        if (StrUtil.isNotEmpty(user.getFaceUrl())) {
                            templateUser.setFaceUrl(user.getFaceUrl());
                            if (user.getFaceUrl().indexOf("https") < 0) {
                                templateUser.setFaceUrl(imgPrefix + user.getFaceUrl());
                            }
                        }
                    }

                    QueryWrapper<ExamineApproveRegAdminRecord> qwAdminRecord = new QueryWrapper<>();
                    qwAdminRecord.eq("approve_record_id", recordId);
                    qwAdminRecord.eq("template_user_id",templateUser.getId());
                    qwAdminRecord.eq("user_id", templateUser.getUserId());
                    qwAdminRecord.last("limit 1");
                    ExamineApproveRegAdminRecord adminRecord = approveRegAdminRecordMapper.selectOne(qwAdminRecord);
                    if(adminRecord != null){
                        templateUser.setAdminRecord(adminRecord);
                    }else{
                        adminRecord = new ExamineApproveRegAdminRecord();
                        adminRecord.setState(0);
                        templateUser.setAdminRecord(adminRecord);
                    }
                }
            }
            regRecord.setCopyTemplateUsers(copyTemplateUsers);
        }
        return regRecord;
    }

    @Override
    @Transactional
    public int addRecord(User user, ExamineApprove approve,  ExamineApproveRegRecord regRecord, JSONArray regInfos, SysUser sysUser) {
        int ret = 0;
        try{
            regRecord.setApproveTitle(approve.getApproveTitle()+"审批");
            regRecord.setPropertyId(sysUser.getPropertyId());
            regRecord.setEstateId(sysUser.getEstateId());
            regRecord.setCreateTime(new Date());
            regRecord.setApproveNo(OrderUtil.getOrderNoByTimespan("E"));

            Property property = propertyService.findById(sysUser.getPropertyId());
            if(property!=null){
                regRecord.setPropertyName(property.getPropertyName());
            }

            Estate estate = estateService.findById(sysUser.getEstateId());
            if(estate != null){
                regRecord.setEstateName(estate.getEstateName());
            }

            ret = approveRegRecordMapper.insert(regRecord);
            if(ret <= 0){
                throw new TransactionalException("approveRegRecordMapper insert error");
            }

            if(regInfos.size() > 0){
                List<ExamineApproveRegInfo> infos = JSONUtil.toList(regInfos,ExamineApproveRegInfo.class);
                if(CollUtil.isNotEmpty(infos)){
                    for (ExamineApproveRegInfo info : infos){
                        info.setApproveRecordId(regRecord.getId());
                        ret = approveRegInfoMapper.insert(info);
                        if(ret <= 0){
                            throw new TransactionalException("approveRegInfoMapper insert error");
                        }
                    }
                }
            }

            ExamineApproveRegAdminRecord regAdminRecord = new ExamineApproveRegAdminRecord();
            regAdminRecord.setCreateTime(new Date());
            regAdminRecord.setApproveRecordId(regRecord.getId());
            regAdminRecord.setTemplateId(approve.getTemplateId());
//            regAdminRecord.setContent("");
            regAdminRecord.setState(0);
            QueryWrapper<ExamineApproveTemplateUser> qw = new QueryWrapper<>();
            qw.eq("template_id", approve.getTemplateId());
            qw.eq("state", 1);
            qw.orderByAsc("duty_index");
            qw.last("limit 1");
            ExamineApproveTemplateUser templateUser = approveTemplateUserMapper.selectOne(qw);
            if(templateUser != null) {
                regAdminRecord.setHandleSort(templateUser.getDutyIndex());
                regAdminRecord.setUserId(templateUser.getUserId());
                regAdminRecord.setTemplateUserId(templateUser.getId());
                ret = approveRegAdminRecordMapper.insert(regAdminRecord);
                if (ret <= 0) {
                    throw new TransactionalException("approveRegAdminRecordMapper insert error");
                }

                //给当前用户发送推送消息
                wxTemplateService.sendWxMsgExamineApproveToNext(approve, templateUser, regRecord, regAdminRecord, 0);

            }

            ret = regRecord.getId();

        }catch (Exception e){
            e.printStackTrace();
            throw new TransactionalException("approveRegInfoMapper insert error");
        }
        return ret;
    }

    @Override
    public int updateRecord(User user, ExamineApprove approve, ExamineApproveRegRecord regRecord, JSONArray regInfos, SysUser sysUser) {
        int ret = 0;
        try{
            regRecord.setState(0);
            regRecord.setApproveTitle(approve.getApproveTitle()+"审批");
            ret = approveRegRecordMapper.updateById(regRecord);
            if(ret <= 0){
                throw new TransactionalException("approveRegRecordMapper updateById error");
            }

            if(regInfos.size() > 0){
                List<ExamineApproveRegInfo> infos = JSONUtil.toList(regInfos,ExamineApproveRegInfo.class);
                if(CollUtil.isNotEmpty(infos)){
                    for (ExamineApproveRegInfo info : infos){
                        if(info.getId()!= null){
//                            info.setApproveRecordId(regRecord.getId());
                            ret = approveRegInfoMapper.updateById(info);
                            if(ret <= 0){
                                throw new TransactionalException("approveRegInfoMapper updateById error");
                            }
                        }else{
                            info.setApproveRecordId(regRecord.getId());
                            ret = approveRegInfoMapper.insert(info);
                            if(ret <= 0){
                                throw new TransactionalException("approveRegInfoMapper insert error");
                            }
                        }
                    }
                }
            }


            //删除之前的审批信息
            approveRegAdminRecordMapper
                    .delete(new LambdaQueryWrapper<ExamineApproveRegAdminRecord>().eq(ExamineApproveRegAdminRecord::getApproveRecordId, regRecord.getId()));


            ExamineApproveRegAdminRecord regAdminRecord = new ExamineApproveRegAdminRecord();
            regAdminRecord.setCreateTime(new Date());
            regAdminRecord.setApproveRecordId(regRecord.getId());
            regAdminRecord.setTemplateId(approve.getTemplateId());
            regAdminRecord.setState(0);
            regAdminRecord.setHandleSort(0);
            QueryWrapper<ExamineApproveTemplateUser> qw = new QueryWrapper<>();
            qw.eq("template_id", approve.getTemplateId());
            qw.eq("state", 1);
            qw.orderByAsc("duty_index");
            qw.last("limit 1");
            ExamineApproveTemplateUser templateUser = approveTemplateUserMapper.selectOne(qw);
            if(templateUser != null) {
                regAdminRecord.setUserId(templateUser.getUserId());
                regAdminRecord.setTemplateUserId(templateUser.getId());
                ret = approveRegAdminRecordMapper.insert(regAdminRecord);
                if (ret <= 0) {
                    throw new TransactionalException("approveRegAdminRecordMapper insert error");
                }

                //给当前用户发送推送消息
                wxTemplateService.sendWxMsgExamineApproveToNext(approve, templateUser, regRecord, regAdminRecord, 0);

            }


            ret = regRecord.getId();

        }catch (Exception e){
            e.printStackTrace();
            throw new TransactionalException("approveRegInfoMapper insert error");
        }
        return ret;
    }

    @Override
    @Transactional
    public int cancelRecord(User user, ExamineApproveRegRecord regRecord) {
        int ret = 0;
        try{
            //审批的状态 0 - 待审批  1 - 审批中  2 - 审核通过  3 - 撤销审批 4 - 审核拒绝
            regRecord.setState(3);
            regRecord.setCancelTime(new Date());
            ret = approveRegRecordMapper.updateById(regRecord);

            ExamineApprove examineApprove = approveMapper.selectById(regRecord.getApproveId());
            if(examineApprove != null){
                //发送给用户 推送消息  撤销审批
                wxTemplateService.sendWxMsgExamineApproveToUser(examineApprove, user, regRecord);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return ret;
    }

    @Override
    public List<ExamineApproveRegRecord> getMyRegRecordList(User user, int approveType, int pageIndex, int pageSize) {

        QueryWrapper<ExamineApproveRegRecord> qw =new QueryWrapper<>();
        qw.eq("user_id",user.getId());
        qw.eq("approve_type",approveType);
        qw.orderByDesc("create_time");
        List<ExamineApproveRegRecord> list = approveRegRecordMapper.getPageEntityList(qw,pageIndex,pageSize);
        if(CollUtil.isNotEmpty(list)){
            for (ExamineApproveRegRecord record : list){
                user = userService.findById(record.getUserId());
                if(user!=null){
                    if(StrUtil.isNotEmpty(user.getNickName())){
                        record.setNickName(EmojiParser.parseToUnicode(user.getNickName()));
                    }
                    if(StrUtil.isNotEmpty(user.getFaceUrl())){
                        if(!user.getFaceUrl().contains("https")){
                            record.setFaceUrl(imgPrefix + user.getFaceUrl());
                        }else{
                            record.setFaceUrl(user.getFaceUrl());
                        }
                    }
                }
            }
        }
        return list;
    }

    @Override
    public List<ExamineApproveRegRecord> getMyRegRecordListByState(User user, int state, int pageIndex, int pageSize) {

        QueryWrapper<ExamineApproveRegRecord> qw =new QueryWrapper<>();
        qw.eq("user_id",user.getId());
        if(state == 0){
            qw.in("state", 0,1);
        } else if(state == 1){
            qw.eq("state", 2);
        } else if(state == 2){
            qw.eq("state", 3);
        } else if(state == 3){
            qw.eq("state", 4);
        }

        qw.orderByDesc("create_time");
        List<ExamineApproveRegRecord> list = approveRegRecordMapper.getPageEntityList(qw,pageIndex,pageSize);
        if(CollUtil.isNotEmpty(list)){
            for (ExamineApproveRegRecord record : list){
                user = userService.findById(record.getUserId());
                if(user != null){
                    if(StrUtil.isNotEmpty(user.getNickName())){
                        record.setNickName(EmojiParser.parseToUnicode(user.getNickName()));
                    }
                    if(StrUtil.isNotEmpty(user.getFaceUrl())){
                        if(!user.getFaceUrl().contains("https")){
                            record.setFaceUrl(imgPrefix + user.getFaceUrl());
                        }else{
                            record.setFaceUrl(user.getFaceUrl());
                        }
                    }
                }
            }
        }
        return list;
    }

    @Override
    public List<ExamineApproveRegRecord> getAdminHandleList(User user, int approveType, int pageIndex, int pageSize) {
        Map<String,Object> map = new HashMap<>();
        map.put("userId",user.getId());
        map.put("approveType", approveType);
        int offset = (pageIndex - 1) * pageSize;
        List<ExamineApproveRegRecord> list = approveRegRecordMapper.getAdminHandleList(map,offset,pageSize);
        if(CollUtil.isNotEmpty(list)){
            for (ExamineApproveRegRecord record : list){
                user = userService.findById(record.getUserId());
                if(user!=null){
                    if(StrUtil.isNotEmpty(user.getNickName())){
                        record.setNickName(EmojiParser.parseToUnicode(user.getNickName()));
                    }
                    if(StrUtil.isNotEmpty(user.getFaceUrl())){
                        if(!user.getFaceUrl().contains("https")){
                            record.setFaceUrl(imgPrefix + user.getFaceUrl());
                        }else{
                            record.setFaceUrl(user.getFaceUrl());
                        }
                    }
                }
            }
        }

        return list;
    }

    @Override
    public List<ExamineApproveRegRecord> getAdminHandleListByState(User user, int state, String searchValue, int pageIndex, int pageSize) {
        Map<String,Object> map = new HashMap<>();
        map.put("userId",user.getId());
        map.put("state", state);
        map.put("keyword", searchValue);
        int offset = (pageIndex - 1) * pageSize;
        List<ExamineApproveRegRecord> list = approveRegRecordMapper.getAdminHandleList(map, offset, pageSize);
        if(CollUtil.isNotEmpty(list)){
            for (ExamineApproveRegRecord record : list){
                user = userService.findById(record.getUserId());
                if(user!=null){
                    if(StrUtil.isNotEmpty(user.getNickName())){
                        record.setNickName(EmojiParser.parseToUnicode(user.getNickName()));
                    }
                    if(StrUtil.isNotEmpty(user.getFaceUrl())){
                        if(!user.getFaceUrl().contains("https")){
                            record.setFaceUrl(imgPrefix + user.getFaceUrl());
                        }else{
                            record.setFaceUrl(user.getFaceUrl());
                        }
                    }
                }
            }
        }

        return list;
    }

    @Override
    public List<ExamineApproveRegRecord> getAdminCopyListByState(User user, int state, String searchValue, int pageIndex, int pageSize) {
        Map<String,Object> map = new HashMap<>();
        map.put("userId",user.getId());
        map.put("state", state);
        map.put("keyword", searchValue);
        int offset = (pageIndex - 1) * pageSize;
        List<ExamineApproveRegRecord> list = approveRegRecordMapper.getAdminCopyList(map, offset, pageSize);
        if(CollUtil.isNotEmpty(list)){
            for (ExamineApproveRegRecord record : list){
                user = userService.findById(record.getUserId());
                if(user!=null){
                    if(StrUtil.isNotEmpty(user.getNickName())){
                        record.setNickName(EmojiParser.parseToUnicode(user.getNickName()));
                    }
                    if(StrUtil.isNotEmpty(user.getFaceUrl())){
                        if(!user.getFaceUrl().contains("https")){
                            record.setFaceUrl(imgPrefix + user.getFaceUrl());
                        }else{
                            record.setFaceUrl(user.getFaceUrl());
                        }
                    }
                }
            }
        }

        return list;
    }

    @Override
    public int getAdminHandleCount(User user, int state) {
        Map<String, Object> map = new HashMap<>();
        map.put("userId",user.getId());
        map.put("state", state);
        return approveRegRecordMapper.getAdminHandleCount(map);
    }
}
